package com.hospital.hospitalserver.service;


import com.hospital.hospitalserver.entity.HomeStatsData;
import com.hospital.hospitalserver.entity.SystemStatus;
import com.hospital.hospitalserver.mapper.StatisticsMapper;
import com.hospital.hospitalserver.util.Response;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.SystemInfo;
import oshi.software.os.OSFileStore;
import lombok.extern.slf4j.Slf4j;


/**
 * 数据统计实现类
 * */
@Slf4j
@Service
@RequiredArgsConstructor
public class StatisticsService {
    private final StatisticsMapper statisticsMapper;
    private static final SystemInfo SYSTEM_INFO = new SystemInfo();

    public Response getHomeStatsData(){
        HomeStatsData homeStatsData = statisticsMapper.getHomeStatsData();
        SystemStatus status = getSystemStatus();
        //添加数据
        homeStatsData.setCpuUsage(status.getCpuUsage());
        homeStatsData.setMemoryUsage(status.getMemoryUsage());
        homeStatsData.setDiskUsage(status.getDiskUsage());
        return Response.success(homeStatsData);
    }

    /**
     * 获取系统状态信息 - 简化版本
     */
    public SystemStatus getSystemStatus() {
        SystemStatus status = new SystemStatus();

        try {
            status.setCpuUsage(getCpuUsage());
            status.setMemoryUsage(getMemoryUsage());
            status.setDiskUsage(getDiskUsage());
        } catch (Exception e) {
//            log.error("获取系统状态失败", e);
        }

        return status;
    }

    /**
     * 获取CPU使用率（百分比，0-100）
     */
    private static Double getCpuUsage() {
        try {
            CentralProcessor processor = SYSTEM_INFO.getHardware().getProcessor();

            // 方法1：使用getSystemCpuLoadBetweenTicks（推荐）
            return getCpuUsageWithBetweenTicks(processor);

        } catch (Exception e) {
            log.error("获取CPU使用率失败", e);
            return 0.0;
        }
    }

    /**
     * 使用getSystemCpuLoadBetweenTicks方法获取CPU使用率
     */
    private static Double getCpuUsageWithBetweenTicks(CentralProcessor processor) {
        try {
            // 第一次采样
            long[] prevTicks = processor.getSystemCpuLoadTicks();

            // 等待1秒进行第二次采样
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return 0.0;
            }

            // 使用正确的方法获取CPU负载
            double cpuLoad = processor.getSystemCpuLoadBetweenTicks(prevTicks);

            // 转换为百分比
            double cpuUsage = cpuLoad * 100;
            return formatDouble(cpuUsage);

        } catch (Exception e) {
            log.error("使用getSystemCpuLoadBetweenTicks获取CPU使用率失败", e);
            return getCpuUsageManual(processor);
        }
    }

    /**
     * 手动计算CPU使用率（备选方案）
     */
    private static Double getCpuUsageManual(CentralProcessor processor) {
        try {
            // 第一次采样
            long[] prevTicks = processor.getSystemCpuLoadTicks();

            // 等待1秒
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return 0.0;
            }

            // 第二次采样
            long[] currentTicks = processor.getSystemCpuLoadTicks();

            // 计算各种状态的时间差
            long user = currentTicks[CentralProcessor.TickType.USER.getIndex()] -
                    prevTicks[CentralProcessor.TickType.USER.getIndex()];
            long nice = currentTicks[CentralProcessor.TickType.NICE.getIndex()] -
                    prevTicks[CentralProcessor.TickType.NICE.getIndex()];
            long system = currentTicks[CentralProcessor.TickType.SYSTEM.getIndex()] -
                    prevTicks[CentralProcessor.TickType.SYSTEM.getIndex()];
            long idle = currentTicks[CentralProcessor.TickType.IDLE.getIndex()] -
                    prevTicks[CentralProcessor.TickType.IDLE.getIndex()];
            long iowait = currentTicks[CentralProcessor.TickType.IOWAIT.getIndex()] -
                    prevTicks[CentralProcessor.TickType.IOWAIT.getIndex()];
            long irq = currentTicks[CentralProcessor.TickType.IRQ.getIndex()] -
                    prevTicks[CentralProcessor.TickType.IRQ.getIndex()];
            long softirq = currentTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()] -
                    prevTicks[CentralProcessor.TickType.SOFTIRQ.getIndex()];
            long steal = currentTicks[CentralProcessor.TickType.STEAL.getIndex()] -
                    prevTicks[CentralProcessor.TickType.STEAL.getIndex()];

            // 计算总时间差和空闲时间差
            long totalCpu = user + nice + system + idle + iowait + irq + softirq + steal;
            long totalIdle = idle + iowait;

            if (totalCpu == 0) {
                return 0.0;
            }

            // 计算CPU使用率
            double cpuUsage = (1.0 - (double) totalIdle / totalCpu) * 100;
            return formatDouble(cpuUsage);

        } catch (Exception e) {
            log.error("手动计算CPU使用率失败", e);
            return 0.0;
        }
    }

    /**
     * CPU使用率备选计算方法
     */
    private static Double getCpuUsageFallback() {
        try {
            CentralProcessor processor = SYSTEM_INFO.getHardware().getProcessor();

            long[] prevTicks = processor.getSystemCpuLoadTicks();

            try {
                Thread.sleep(500); // 等待500毫秒
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return 0.0;
            }

            // 正确使用方法：只传入前一次的ticks
            double cpuLoad = processor.getSystemCpuLoadBetweenTicks(prevTicks);
            return formatDouble(cpuLoad * 100);

        } catch (Exception e) {
            log.error("备选CPU使用率计算方法也失败了", e);
            return 0.0;
        }
    }

    // 其他方法保持不变...
    private static Double getMemoryUsage() {
        try {
            GlobalMemory memory = SYSTEM_INFO.getHardware().getMemory();
            long totalMemory = memory.getTotal();
            long availableMemory = memory.getAvailable();

            if (totalMemory == 0) return null;

            double memoryUsage = (totalMemory - availableMemory) * 100.0 / totalMemory;
            return formatDouble(memoryUsage);

        } catch (Exception e) {
            log.error("获取内存使用率失败", e);
            return null;
        }
    }

    private static Double getDiskUsage() {
        try {
            OSFileStore[] fileStores = SYSTEM_INFO.getOperatingSystem().getFileSystem().getFileStores().toArray(new OSFileStore[0]);
            if (fileStores.length == 0) return null;

            OSFileStore systemDisk = fileStores[0];
            long totalSpace = systemDisk.getTotalSpace();
            long usableSpace = systemDisk.getUsableSpace();

            if (totalSpace == 0) return null;

            double diskUsage = (totalSpace - usableSpace) * 100.0 / totalSpace;
            return formatDouble(diskUsage);

        } catch (Exception e) {
            log.error("获取磁盘使用率失败", e);
            return null;
        }
    }

    private static Double formatDouble(double value) {
        return Math.round(value * 100.0) / 100.0;
    }
}
